#pragma once

#include <AVUITriggerBase.h>

namespace AVUI {

/// <summary>Initializes a new instance of the <see cref="T:System.Windows.EventTrigger" /> class. </summary>
class EventTrigger : public TriggerBase
{
public:
    DECLARE_ELEMENT(EventTrigger, TriggerBase);

#pragma region Public Methods

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.EventTrigger" /> class. </summary>
    EventTrigger() : m_childId(0), m_pRoutedEvent(NULL) { }

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.EventTrigger" /> class with the specified event.</summary>
    /// <param name="routedEvent">The <see cref="T:System.Windows.RoutedEvent" /> that activates this trigger.</param>
    EventTrigger(RoutedEvent* pRoutedEvent) : m_childId(0) { set_RoutedEvent(pRoutedEvent); }

#pragma endregion Public Methods

#pragma region Public Properties

    /// <summary>Gets the collection of actions to apply when the event occurs.</summary>
    /// <returns>The default is an empty collection.</returns>
    TriggerActionCollection* get_Actions();
    DECLARE_READONLY_PROPERTY(Actions, TriggerActionCollection, true);

    /// <summary>Gets or sets the <see cref="T:System.Windows.RoutedEvent" /> that will activate this trigger.</summary>
    /// <returns>The default value is null.</returns>
    /// <exception cref="T:System.ArgumentNullException">The <see cref="P:System.Windows.EventTrigger.RoutedEvent" /> property cannot be null.</exception>
    RoutedEvent* get_RoutedEvent() { return m_pRoutedEvent; }
    void set_RoutedEvent(RoutedEvent* pValue);
    DECLARE_PROPERTY(RoutedEvent, RoutedEvent, false);

    /// <summary>Gets or sets the name of the object with the event that activates this trigger. This is only used by element triggers or template triggers.</summary>
    /// <returns>The default value is null. If this property value is null, then the element being monitored for the raising of the event is the templated parent or the logical tree root.</returns>
    /// <exception cref="T:System.InvalidOperationException">After an <see cref="T:System.Windows.EventTrigger" /> is in use, it cannot be modified.</exception>
    String* get_SourceName() { return m_pSourceName; }
    void set_SourceName(String* pValue);
    DECLARE_PROPERTY(SourceName, String, false);

#pragma endregion Public Properties

public:

#pragma region Internal Methods

    static void DisconnectAllTriggers(FrameworkElement* pTriggersHost);
    static void DisconnectOneTrigger(FrameworkElement* pTriggersHost, TriggerBase* pTriggerBase);
    virtual void OnInheritanceContextChangedCore(EventArgs* pArgs) AVUI_OVERRIDE;
    static void ProcessOneTrigger(FrameworkElement* pTriggersHost, TriggerBase* pTriggerBase);
    static void ProcessTriggerCollection(FrameworkElement* pTriggersHost);
    virtual void Seal() AVUI_OVERRIDE;

#pragma endregion Internal Methods

#pragma region Internal Properties

    int get_TriggerChildIndex() { return m_childId; }
    void set_TriggerChildIndex(int value) { m_childId = value; }

#pragma endregion Internal Properties

#pragma region Internal Fields

    static UncommonField<TriggerCollection> TriggerCollectionField;

#pragma endregion Internal Fields

private:

#pragma region Private Fields

    TRefCountedPtr<TriggerActionCollection> m_pActions;
    int m_childId;
    RoutedEvent* m_pRoutedEvent;
    TRefCountedPtr<RoutedEventHandler> m_pRoutedEventHandler;
    TWeakPtr<FrameworkElement> m_pSource;
    TRefCountedPtr<String> m_pSourceName;

#pragma endregion Private Fields

#pragma region Private Helper

class EventTriggerSourceListener : public Object
{
public:
    EventTriggerSourceListener(EventTrigger* pTrigger, FrameworkElement* pHost) : m_pOwningTrigger(pTrigger), m_pOwningTriggerHost(pHost) { }
    void Handler(Object* pSender, RoutedEventArgs* e);
private:
    EventTrigger* m_pOwningTrigger;
    FrameworkElement* m_pOwningTriggerHost;
};

#pragma endregion Private Helper

#pragma region WPFG/Deviation

    // We ref the listeners so they don't go out of scope.
    ItemStructList< TRefCountedPtr<EventTriggerSourceListener> > m_rgListeners;

#pragma endregion WPFG/Deviation

};



}; // namespace AVUI
